package com.woniuxy.project115.kaer.tenant.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.project115.kaer.tenant.config.WebSocketServer;
import com.woniuxy.project115.kaer.tenant.entity.*;
import com.woniuxy.project115.kaer.tenant.mapper.*;
import com.woniuxy.project115.kaer.tenant.param.AddAppointmentParam;
import com.woniuxy.project115.kaer.tenant.param.GetAppointmentParam;
import com.woniuxy.project115.kaer.tenant.service.AppointmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.project115.kaer.tenant.util.Data;
import com.woniuxy.project115.kaer.user.dto.UserInfoDto;
import com.woniuxy.project115.kaer.user.feign.UserFeignClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author HuH
 * @since 2025年02月18日
 */
@Service
public class AppointmentServiceImpl extends ServiceImpl<AppointmentMapper, Appointment> implements AppointmentService {
    @Resource
    private AppointmentMapper appointmentMapper;

    @Resource
    private AppointmentItemMapper appointmentItemMapper;

    @Resource
    private ServiceInfoMapper serviceInfoMapper;

    @Resource
    private ServiceInfoItemMapper serviceInfoItemMapper;

    @Resource
    private ServiceOrderMapper serviceOrderMapper;

    @Resource
    private OrderLogMapper orderLogMapper;

    @Resource
    private TenantInfoMapper tenantInfoMapper;

    @Resource
    private UserFeignClient userFeignClient;

    @Override
    public void addAppointment(AddAppointmentParam param, Integer userId) throws Exception {
        UserInfoDto userInfo = userFeignClient.getAllUserInfo(userId).getData();

        ServiceInfo serviceInfo = serviceInfoMapper.selectById(param.getServiceInfoId());
        if (serviceInfo == null) {
            throw new Exception("服务商品信息不存在");
        }
        if (serviceInfo.getState() == Data.SERVICE_INFO_OFFLINE) {
            throw new Exception("服务商品信息已下架");
        }
        Appointment appointment = BeanUtil.toBean(param, Appointment.class);

        appointment.setUserId(userId)
                .setUserName(userInfo.getNickName())
                .setUserPhone(userInfo.getPhone())
                .setTypeName(serviceInfo.getTypeName())
                .setTotalPrice(serviceInfo.getTotalPrice())
                .setState(Data.APPOINTMENT_WAIT_CONFIRMED_NC)
                .setStoreId(serviceInfo.getStoreId())
                .setStoreName(serviceInfo.getStoreName())
                .setCreateTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")));
        appointmentMapper.insert(appointment);

        List<ServiceInfoItem> list = serviceInfoItemMapper.selectList(new QueryWrapper<ServiceInfoItem>().eq("service_info_id", serviceInfo.getServiceInfoId()));
        if (list != null) {
            for (ServiceInfoItem infoItem : list) {
                appointmentItemMapper.insert(
                        new AppointmentItem()
                                .setItemName(infoItem.getItemName())
                                .setMaterial(infoItem.getMaterial())
                                .setUnitPrice(infoItem.getUnitPrice())
                                .setNumber(infoItem.getNumber())
                                .setLaborCost(infoItem.getLaborCost())
                                .setAppointmentId(appointment.getAppointmentId())
                                .setState(Data.APPOINTMENT_ITEM_WAIT_CONFIRMED));
            }
        }

        //通知商家及时查看预约
        TenantInfo tenantInfo = tenantInfoMapper.selectOne(new QueryWrapper<TenantInfo>().eq("store_id", serviceInfo.getStoreId()));
        WebSocketServer.sendInfo("您有一条新的服务预约，请及时查看", "sj" + tenantInfo.getTenantInfoId());
    }

    @Override
    public void userCancelAppointment(Integer appointmentId) throws Exception {
        Appointment appointment = appointmentMapper.selectById(appointmentId)
                .setState(Data.APPOINTMENT_CANCELLED)
                .setEndTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")));
        appointmentMapper.updateById(appointment);

        appointmentItemMapper.selectList(new QueryWrapper<AppointmentItem>().eq("appointment_id", appointmentId))
                .forEach(appointmentItem -> appointmentItemMapper.deleteById(appointmentItem.getItemId()));
    }

    @Override
    public void confirm(Integer appointmentId) throws Exception {
        Appointment appointment = appointmentMapper.selectById(appointmentId);
        appointment.setState(Data.APPOINTMENT_CONFIRMED);

        ServiceOrder serviceOrder = new ServiceOrder();
        serviceOrder.setAppointmentId(appointmentId)
                .setTotalPrice(appointment.getTotalPrice())
                .setState(Data.SERVICE_ORDER_WAIT_SERVICE)
                .setPayState(Data.PAY_STATE_NOT_PAY)
                .setRemarks(appointment.getRemarks())
                .setStoreId(appointment.getStoreId())
                .setStoreName(appointment.getStoreName())
                .setUserId(appointment.getUserId())
                .setUserName(appointment.getUserName())
                .setUserPhone(appointment.getUserPhone())
                .setVehicleNum(appointment.getVehicleNum())
                .setBrandName(appointment.getBrandName())
                .setVehicleName(appointment.getVehicleName())
                .setCreateTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))
                .setTypeName(appointment.getTypeName());

//        //通过时间戳生成订单号
//        LocalDateTime now = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
//        serviceOrder.setCreateTime(now);
//        String orderNum = now.toString().replaceAll(":", "").replaceAll("-", "").replaceAll(" ", "").substring(0, 12);
//        serviceOrder.setServiceOrderNum(orderNum);
        //生成随机的订单编号 雪花
        Snowflake snowflake = new Snowflake(1, 1);
        String orderNum = snowflake.nextIdStr();
        serviceOrder.setServiceOrderNum(orderNum);
        serviceOrderMapper.insert(serviceOrder);

        appointment.setOrderNum(orderNum);
        appointmentMapper.updateById(appointment);

        List<AppointmentItem> itemList = appointmentItemMapper.selectList(new QueryWrapper<AppointmentItem>().eq("appointment_id", appointmentId));
        for (AppointmentItem item : itemList) {
            item.setServiceOrderNum(orderNum)
                            .setState(Data.APPOINTMENT_ITEM_CONFIRMED);
            appointmentItemMapper.updateById(item);
        }

        //更新订单操作日志
        orderLogMapper.insert(
                new OrderLog()
                        .setOperator("商家")
                        .setServiceOrderNum(orderNum)
                        .setOperateTime(serviceOrder.getPayTime())
                        .setOperateType("确认服务，生成订单")
        );
    }

    @Override
    public Page<Appointment> getAppointment(GetAppointmentParam param, Integer storeId) throws Exception {
        Page<Appointment> page = new Page<>(param.getPageNum(), param.getPageSize());
        QueryWrapper<Appointment> queryWrapper = new QueryWrapper<>();
        if (param.getTypeName() != null && !param.getTypeName().isEmpty()) {
            queryWrapper.eq("type_name", param.getTypeName());
        }
        if (param.getState() != null && param.getState() != -1) {
            queryWrapper.eq("state", param.getState());
        }
        queryWrapper.eq("store_id", storeId);
        Page<Appointment> appointmentPage = appointmentMapper.selectPage(page, queryWrapper);
        for (Appointment appointment : appointmentPage.getRecords()) {
            //如果当前时间大于预约时间，则修改预约状态为可取消的
            if (appointment.getState() == Data.APPOINTMENT_WAIT_CONFIRMED_NC && appointment.getArrivalTime().isBefore(LocalDateTime.now(ZoneId.of("Asia/Shanghai")))) {
                appointment.setState(Data.APPOINTMENT_WAIT_CONFIRMED_C);
                appointmentMapper.updateById(appointment);
            }
        }
        return appointmentPage;
    }
}
